import {
  isUndefined,
  isNull,
  PagedList,
  PageParams,
  BackendServices,
  StringIndexerTo,
  StringIndexer,
  toString,
  underscoreToCamelCase,
} from "mmb";

import * as wxpaypb from "../grpc-client/proxy/wxpay_pb";
import { Empty } from "google-protobuf/google/protobuf/empty_pb";
import {
  WxpayApplyFormData,
  WxpayApplyment,
  BizLicenseInfo,
  OrganizationCertInfo,
  IDCardInfo,
  IDDocInfo,
  AccountInfo,
  ContactInfo,
  SalesSceneInfo,
} from "../service/declareTypes";
import {
  getWxpayProxySafely,
  getMetadata,
  getOptionsOfLight,
  getOptionsOfHeavy,
  wrapperGrpcError,
} from "../grpc-client/grpcAdapter";
import { getMchIdAsServiceVar } from "../store/vars";

export const healthCheck = async (): Promise<string> => {
  const cl = getWxpayProxySafely();
  const req = new Empty();

  return new Promise((resolve, reject) => {
    cl.dummyHandler(req, getMetadata(), getOptionsOfLight(), (err, res) => {
      if (!isNull(err)) {
        console.log("err=>", err);
        reject(wrapperGrpcError(err.details));
        return;
      }
      if (!res.getMessage()) {
        reject("no response of wxpay");
        return;
      }
      resolve(res.getMessage());
    });
  });
};

export const imageUpload = async (
  data: string,
  imageType: string
): Promise<string> => {
  const cl = getWxpayProxySafely();
  const req = new wxpaypb.ImageUploadRequest();
  req.setImage(data);
  req.setMchId(getMchIdAsServiceVar());
  req.setImageType(imageType);

  return new Promise((resolve, reject) => {
    cl.imageUpload(req, getMetadata(), getOptionsOfHeavy(), (err, res) => {
      if (!isNull(err)) {
        console.log("err=>", err);
        reject(wrapperGrpcError(err.details));
        return;
      }
      resolve(res.getMediaId());
    });
  });
};

export interface ApplymentSubmitParams extends WxpayApplyFormData {
  sgId: string;
  bizApplyNo: string; // 'bg'+applyment.id
}

export const applymentSubmit = async (
  {
    sgId,
    bizApplyNo,
    applyType, // ecommerce/apply4sub
    // 商户号
    mchId,
    // 主体类型
    organizationType, // 2401~小微商户,2~企业 4~个体工商户
    // 营业执照/登记证书信息
    bizLicenseInfo,
    // 组织机构代码证信息
    organizationCertInfo,
    // 经营者/法人证件类型
    idDocType,
    // 经营者/法人身份证信息
    idCardInfo,
    // 经营者/法人其他类型证件信息
    idDocInfo,
    // 是否填写结算银行账户
    needAccountInfo,
    // 结算银行账户
    accountInfo,
    // 超级管理员信息
    contactInfo,
    // 店铺信息
    salesSceneInfo,
    // 商户简称
    merchantShortname,
    // 特殊资质
    qualifications,
    // 补充材料
    businessAdditionPics,
    // 补充说明
    businessAdditionDesc,
  }: ApplymentSubmitParams,
  isResubmit: boolean = false
): Promise<string> => {
  const cl = getWxpayProxySafely();
  const req = new wxpaypb.ApplymentSubmitRequest();

  req.setBrandId(sgId);
  req.setBizApplyNo(bizApplyNo);

  req.setApplyType(applyType);
  req.setMchId(mchId);
  req.setOrganizationType(organizationType);
  if (!isUndefined(bizLicenseInfo)) {
    const pb = new wxpaypb.BizLicenseInfo();

    pb.setBusinessLicenseCopy(bizLicenseInfo.businessLicenseCopy);
    pb.setBusinessLicenseNumber(bizLicenseInfo.businessLicenseNumber);
    pb.setMerchantName(bizLicenseInfo.merchantName);
    pb.setLegalPerson(bizLicenseInfo.legalPerson);
    if (!isUndefined(bizLicenseInfo.companyAddress)) {
      pb.setCompanyAddress(bizLicenseInfo.companyAddress);
    }
    if (!isUndefined(bizLicenseInfo.businessTime)) {
      pb.setBusinessTime(bizLicenseInfo.businessTime);
    }

    req.setBizLicenseInfo(pb);
  }
  if (!isUndefined(organizationCertInfo)) {
    const pb = new wxpaypb.OrganizationCertInfo();

    pb.setOrganizationCopy(organizationCertInfo.organizationCopy);
    pb.setOrganizationNumber(organizationCertInfo.organizationNumber);
    pb.setOrganizationTime(organizationCertInfo.organizationTime);

    req.setOrganizationCertInfo(pb);
  }
  req.setIdDocType(idDocType!);
  if (!isUndefined(idCardInfo)) {
    const pb = new wxpaypb.IDCardInfo();

    pb.setIdCardCopy(idCardInfo.idCardCopy);
    pb.setIdCardNational(idCardInfo.idCardNational);
    pb.setIdCardName(idCardInfo.idCardName);
    pb.setIdCardNumber(idCardInfo.idCardNumber);
    pb.setIdCardValidTime(idCardInfo.idCardValidTime);

    req.setIdCardInfo(pb);
  }
  if (!isUndefined(idDocInfo)) {
    const pb = new wxpaypb.IDDocInfo();

    pb.setIdDocName(idDocInfo.idDocName);
    pb.setIdDocNumber(idDocInfo.idDocNumber);
    pb.setIdDocCopy(idDocInfo.idDocCopy);
    pb.setDocPeriodEnd(idDocInfo.docPeriodEnd);

    req.setIdDocInfo(pb);
  }
  req.setNeedAccountInfo(needAccountInfo);
  if (needAccountInfo && !isUndefined(accountInfo)) {
    const pb = new wxpaypb.AccountInfo();

    pb.setBankAccountType(accountInfo.bankAccountType);
    pb.setAccountBank(accountInfo.accountBank);
    pb.setAccountName(accountInfo.accountName);
    pb.setBankAddressCode(accountInfo.bankAddressCode);
    if (!isUndefined(accountInfo.bankBranchId)) {
      pb.setBankBranchId(accountInfo.bankBranchId);
    }
    if (!isUndefined(accountInfo.bankName)) {
      pb.setBankName(accountInfo.bankName);
    }
    pb.setAccountNumber(accountInfo.accountNumber);

    req.setAccountInfo(pb);
  }
  const pbContactInfo = new wxpaypb.ContactInfo();
  pbContactInfo.setContactType(contactInfo.contactType);
  pbContactInfo.setContactName(contactInfo.contactName);
  pbContactInfo.setContactIdCardNumber(contactInfo.contactIdCardNumber);
  pbContactInfo.setMobilePhone(contactInfo.mobilePhone);
  if (!isUndefined(contactInfo.contactEmail)) {
    pbContactInfo.setContactEmail(contactInfo.contactEmail);
  }
  req.setContactInfo(pbContactInfo);

  const pbSalesSceneInfo = new wxpaypb.SalesSceneInfo();
  pbSalesSceneInfo.setStoreName(salesSceneInfo.storeName);
  if (!isUndefined(salesSceneInfo.storeUrl)) {
    pbSalesSceneInfo.setStoreUrl(salesSceneInfo.storeUrl);
  }
  if (!isUndefined(salesSceneInfo.storeQrCode)) {
    pbSalesSceneInfo.setStoreQrCode(salesSceneInfo.storeQrCode);
  }
  if (!isUndefined(salesSceneInfo.miniProgramSubAppid)) {
    pbSalesSceneInfo.setMiniProgramSubAppid(salesSceneInfo.miniProgramSubAppid);
  }
  req.setSalesSceneInfo(pbSalesSceneInfo);
  req.setMerchantShortname(merchantShortname);
  if (!isUndefined(qualifications)) {
    req.setQualificationsList(qualifications);
  }
  if (!isUndefined(businessAdditionPics)) {
    req.setBusinessAdditionPicsList(businessAdditionPics);
  }
  if (!isUndefined(businessAdditionDesc)) {
    req.setBusinessAdditionDesc(businessAdditionDesc);
  }

  return new Promise((resolve, reject) => {
    if (isResubmit) {
      // 重新提交
      cl.applymentReSubmit(
        req,
        getMetadata(),
        getOptionsOfLight(),
        (err, res) => {
          if (!isNull(err)) {
            console.log("err=>", err);
            reject(wrapperGrpcError(err.details));
            return;
          }
          resolve(res.getApplyNo());
        }
      );
    } else {
      cl.applymentSubmit(
        req,
        getMetadata(),
        getOptionsOfLight(),
        (err, res) => {
          if (!isNull(err)) {
            console.log("err=>", err);
            reject(wrapperGrpcError(err.details));
            return;
          }
          resolve(res.getApplyNo());
        }
      );
    }
  });
};

export const applymentQuery = async (
  p: WxpayApplyment
): Promise<WxpayApplyment> => {
  const cl = getWxpayProxySafely();
  const req = new wxpaypb.ApplymentQueryRequest();
  req.setBrandId(p.brandId);
  req.setApplyNo(p.applyNo!);

  return new Promise((resolve, reject) => {
    cl.applymentQuery(req, getMetadata(), getOptionsOfLight(), (err, res) => {
      if (!isNull(err)) {
        console.log("err=>", err);
        reject(wrapperGrpcError(err.details));
        return;
      }
      const bizLicenseInfo = res.getBizLicenseInfo();
      if (!isUndefined(bizLicenseInfo)) {
        p.applyFormData.bizLicenseInfo!.copyUrl = bizLicenseInfo.getCopyUrl();
      }
      const organizationCertInfo = res.getOrganizationCertInfo();
      if (!isUndefined(organizationCertInfo)) {
        p.applyFormData.organizationCertInfo!.copyUrl = organizationCertInfo.getCopyUrl();
      }
      const idCardInfo = res.getIdCardInfo();
      if (!isUndefined(idCardInfo)) {
        p.applyFormData.idCardInfo!.cardUrl = idCardInfo.getCardUrl();
        p.applyFormData.idCardInfo!.nationalUrl = idCardInfo.getNationalUrl();
      }
      const idDocInfo = res.getIdDocInfo();
      if (!isUndefined(idDocInfo)) {
        p.applyFormData.idDocInfo!.copyUrl = idDocInfo.getCopyUrl();
      }

      p.wxApplymentId = res.getWxApplymentId();
      p.applyState = res.getApplyState();
      p.applyStateDesc = res.getApplyStateDesc();
      p.signUrl = res.getSignUrl();
      const v = res.getAccountValidation()!;
      p.accountValidation = {
        accountName: v.getAccountName(),
        // 付款卡号
        accountNo: v.getAccountNo(),
        // 汇款金额 （以分为单位）
        payAmount: v.getPayAmount(),
        // 收款卡号
        destinationAccountNumber: v.getDestinationAccountNumber(),
        // 收款户名
        destinationAccountName: v.getDestinationAccountName(),
        // 开户银行
        destinationAccountBank: v.getDestinationAccountBank(),
        // 省市信息
        city: v.getCity(),
        // 备注信息
        remark: v.getRemark(),
        // 汇款截止时间
        deadline: v.getDeadline(),
      };
      p.wxpayMchIdAsSub = res.getSubMchId();
      p.auditDetails = res.getAuditDetailsList()!.map((v) => ({
        paramName: v.getParamName(),
        rejectReason: v.getRejectReason(),
      }));
      p.legalValidationUrl = res.getLegalValidationUrl();
      resolve(p);
    });
  });
};
